package dao

import (
	"common/biz"
	"common/logs"
	"common/utils"
	"context"
	"core/models/db"
	"core/models/entity"
	"core/repo"
	"encoding/json"
	"errors"
	"fmt"
	"framework/msError"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"gorm.io/gorm"
	"hall/models/request"
	hall "hall/pay/entity"
	"time"
)

type MarketDao struct {
	baseDao *BaseDao
	repo    *repo.Manager
}

func (d *MarketDao) Sell(ctx context.Context, tradeLog *entity.TradeSellLog, trade *db.Trade, materialLog *entity.MaterialLog) (*entity.TradeSellLog, *msError.Error) {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	_mdb := d.repo.Mongo
	mtx, _ := _mdb.Client.StartSession()
	_ = mtx.StartTransaction()
	defer mtx.EndSession(ctx)
	var err error
	//1.添加售卖订单
	err = tx.Model(trade).Create(trade).Error
	if err != nil {
		logs.Error("[marketHandler]用户%d MarketSell err:添加售卖订单失败 req=%v,dbErr=%v", trade.UID, trade, err)
		return nil, biz.SqlError
	}
	//2.冻结或扣除数量
	switch trade.Type {
	case 1:
		card := new(db.WarehouseCard)
		err = tx.Model(card).Where("id=? AND uid=?", trade.WID, trade.UID).Update("is_freeze", true).Error
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketSell err:冻结卡牌错误 req=%v,dbErr=%v", trade.UID, trade, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
	case 2:
		material := new(db.WarehouseMaterial)
		err = tx.Model(material).Where("id=? AND uid=? AND num>=?", trade.WID, trade.UID, trade.Num).Update("num", gorm.Expr("num-?", trade.Num)).Error
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketSell err:扣除材料数量失败 req=%v,dbErr=%v", trade.UID, trade, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
		//添加材料变动记录
		materialLog.LinkID = fmt.Sprintf("%d", trade.ID)
		materialLog.LinkTable = trade.TableName()
		_, err = _mdb.Db.Collection("material_log").InsertOne(ctx, materialLog)
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketSell err:添加材料变更失败 req=%v,dbErr=%v", trade.UID, materialLog, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
	case 3:
		port := new(db.WarehouseEquip)
		err = tx.Model(port).Where("id=? AND uid=?", trade.WID, trade.UID).Update("is_freeze", true).Error
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketSell err:冻结装备错误 req=%v,dbErr=%v", trade.UID, trade, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
	}
	tradeLog.OID = trade.ID
	//3.添加mongo售卖订单记录
	_, err = _mdb.Db.Collection("trade_log").InsertOne(ctx, tradeLog)
	if err != nil {
		logs.Error("[marketHandler]用户%d MarketSell err:添加mongo售卖订单记录失败 req=%v,dbErr=%v", trade.UID, tradeLog, err)
		tx.Rollback()
		_ = mtx.AbortTransaction(ctx)
		return nil, biz.SqlError
	}
	_ = mtx.CommitTransaction(ctx)
	tx.Commit()
	return tradeLog, nil
}

func (d *MarketDao) SellAll(ctx context.Context, page, size int, in []int64, uid uint) (int64, *[]db.TradeHasOneType) {
	data := new([]db.TradeHasOneType)
	var count int64
	DB := d.repo.DB.Client.WithContext(ctx).Model(db.Trade{}).Where("uid<>? AND status=? AND type_id IN (?) AND sy_num>0", uid, 0, in)
	DB.Count(&count)
	DB.Preload("Types").Preload("SellTypes").Scopes(db.Paginate(page, size)).Find(data)
	return count, data
}

func (d *MarketDao) GetTrade(ctx context.Context, id uint) *db.TradeHasOneType {
	data := new(db.TradeHasOneType)
	d.repo.DB.Client.WithContext(ctx).Model(db.Trade{}).Where("id=?", id).Preload("Types").Preload("SellTypes").First(data)
	return data
}

func (d *MarketDao) MongoGetOrder(ctx context.Context, cancel int, uid, id uint) *entity.MarketOrder {
	collection := d.repo.Mongo.Db.Collection("trade_order")
	times := time.Now().Unix()
	result := collection.FindOne(ctx, bson.D{
		{"uid", uid},
		{"tradeID", id},
		{"payStatus", entity.TradePayNone},
		{"createTime", bson.D{{"$lte", times - int64(cancel)}}},
	})
	order := new(entity.MarketOrder)
	_ = result.Decode(order)
	return order
}

func (d *MarketDao) MarketCreateOrder(ctx context.Context, order *entity.MarketOrder) (*entity.MarketOrder, *msError.Error) {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	//1.查看商品信息
	var err error
	trade := new(db.Trade)
	g := d.GetTrade(ctx, order.TradeID)
	trade = &g.Trade
	if g == nil {
		logs.Error("[marketHandler]用户%d MarketCreateOrder err:查看商品信息失败 req=%v,dbErr=%v", order.UID, order, err)
		return nil, biz.RequestDataError
	}
	if g.SyNum < order.Num {
		logs.Error("[marketHandler]用户%d MarketCreateOrder err:商品数量不足 req=%v,dbErr=%v", order.UID, order, err)
		return nil, biz.GoodsNumError
	}
	if g.Status != 0 {
		logs.Error("[marketHandler]用户%d MarketCreateOrder err:商品已下架 req=%v,dbErr=%v", order.UID, order, err)
		return nil, biz.GoodsRemoveFromShelvesError
	}
	//2.修改商品数量
	up := make(map[string]any)
	up["sy_num"] = gorm.Expr("sy_num-?", order.Num)
	err = tx.Model(trade).Where("id=?", order.TradeID).Updates(up).Error
	if err != nil {
		logs.Error("[marketHandler]用户%d MarketCreateOrder err:修改商品数量失败 req=%v,dbErr=%v", order.UID, order, err)
		return nil, biz.SqlError
	}
	//3.验证是否材料支付
	if g.SellTypeID != 0 {
		//1.扣除材料
		material := new(db.WarehouseMaterial)
		_db.Model(material).Where("uid=? AND type_id=?", order.UID, order.SellTypeID).First(material)
		if material == nil || material.ID == 0 {
			logs.Error("[marketHandler]用户%d MarketCreateOrder err:材料不足 req=%v,dbErr=%v", order.UID, order, err)
			tx.Rollback()
			return nil, biz.MarketPayError
		}
		if material.Num < order.Num {
			logs.Error("[marketHandler]用户%d MarketCreateOrder err:材料不足 req=%v,dbErr=%v", order.UID, order, err)
			tx.Rollback()
			return nil, biz.MarketPayError
		}
		totalPrice := utils.DecimalFloatByInt(order.TotalPrice)
		err = tx.Model(material).Where("id=?", material.ID).Update("num", gorm.Expr("num-?", totalPrice)).Error
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketCreateOrder err:修改材料失败 req=%v,dbErr=%v", order.UID, order, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
		//2.添加材料变动记录
		collection := d.repo.Mongo.Db.Collection("material_log")
		materialLog := &entity.MaterialLog{
			UID:       order.UID,
			WID:       order.TradeID,
			TypeID:    g.SellTypeID,
			TypeName:  order.SellTypeName,
			TypeImg:   order.SellTypeImg,
			LinkID:    fmt.Sprintf("%d", order.Id),
			LinkTable: fmt.Sprintf("m_trade_order"),
			Ago:       material.Num,
			Num:       -totalPrice,
			After:     material.Num - totalPrice,
			Remarks:   "市场-购买商品",
			AddTime:   time.Now().Format(time.DateTime),
		}
		_, err = collection.InsertOne(ctx, materialLog)
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketCreateOrder err:mongo创建材料日志失败 req=%v,dbErr=%v", order.UID, order, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
		//3.把订单状态改为已完成
		order.PayStatus = entity.TradePay
		order.PayTime = time.Now().Unix()
		order.PayNotify = "材料支付"
		//4.给买家添加购买的商品
		switch g.Type {
		case 1: //卡牌
			warehouse := new(db.WarehouseCard)
			err = tx.Model(warehouse).Where("id=?", trade.WID).Updates(map[string]any{
				"uid":       order.UID,
				"is_freeze": false,
			}).Error
			if err != nil {
				logs.Error("[marketHandler]用户%d MarketCreateOrder err:修改卡牌状态失败 req=%v,dbErr=%v", order.UID, order, err)
				tx.Rollback()
				return nil, biz.SqlError
			}
		case 2: //材料
			material = new(db.WarehouseMaterial)
			_db.Model(material).Where("uid=? AND type_id=?", order.UID, order.TypeID).First(material)
			if material == nil || material.ID == 0 { //不存在 添加
				material = &db.WarehouseMaterial{
					UID:    order.UID,
					TypeID: order.TypeID,
					Num:    order.Num,
				}
				err = tx.Model(material).Create(material).Error
			} else { //存在修改
				err = tx.Model(material).Where("id=?", material.ID).Update("num", gorm.Expr("num+?", order.Num)).Error
			}
			if err != nil {
				logs.Error("[marketHandler]用户%d MarketCreateOrder err:修改材料数量失败 req=%v,dbErr=%v", order.UID, order, err)
				tx.Rollback()
				return nil, biz.SqlError
			}
			//添加仓库材料记录
			collection = d.repo.Mongo.Db.Collection("material_log")
			materialLog = &entity.MaterialLog{
				UID:       order.UID,
				WID:       material.ID,
				TypeID:    material.TypeID,
				TypeName:  order.TypeName,
				TypeImg:   order.TypeImg,
				LinkID:    fmt.Sprintf("%d", order.Id),
				LinkTable: fmt.Sprintf("m_trade_order"),
				Ago:       material.Num,
				Num:       order.Num,
				After:     material.Num + order.Num,
				Remarks:   "市场-获得商品",
				AddTime:   time.Now().Format(time.DateTime),
			}
			_, err = collection.InsertOne(ctx, materialLog)
			if err != nil {
				logs.Error("[marketHandler]用户%d MarketCreateOrder err:mongo创建材料日志失败 req=%v,dbErr=%v", order.UID, order, err)
				tx.Rollback()
				return nil, biz.SqlError
			}
		case 3: //装备
			warehouse := new(db.WarehouseEquip)
			err = tx.Model(warehouse).Where("id=?", trade.WID).Updates(map[string]any{
				"uid":       order.UID,
				"is_freeze": false,
			}).Error
			if err != nil {
				logs.Error("[marketHandler]用户%d MarketCreateOrder err:修改装备状态失败 req=%v,dbErr=%v", order.UID, order, err)
				tx.Rollback()
				return nil, biz.SqlError
			}
		default:
			logs.Error("[marketHandler]用户%d MarketCreateOrder err:商品类型错误 req=%v,dbErr=%v", order.UID, order, err)
			tx.Rollback()
			return nil, biz.Fail
		}
		//5.给卖家添加材料
		material = new(db.WarehouseMaterial)
		_db.Model(material).Where("uid=? AND type_id=?", order.SellUID, order.SellTypeID).First(material)
		total := utils.DecimalFloatByInt(utils.DecimalFloatSub(order.TotalPrice, order.Fee))
		if material == nil || material.ID == 0 { //不存在 添加
			material = &db.WarehouseMaterial{
				UID:    order.SellUID,
				TypeID: order.TypeID,
				Num:    total,
			}
			err = tx.Model(material).Create(material).Error
		} else { //存在修改
			err = tx.Model(material).Where("id=?", material.ID).Update("num", gorm.Expr("num+?", total)).Error
		}
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketCreateOrder err:修改材料数量失败 req=%v,dbErr=%v", order.UID, order, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
		//添加仓库材料记录
		collection = d.repo.Mongo.Db.Collection("material_log")
		materialLog = &entity.MaterialLog{
			UID:       order.SellUID,
			WID:       material.ID,
			TypeID:    material.TypeID,
			TypeName:  order.SellTypeName,
			TypeImg:   order.SellTypeImg,
			LinkID:    fmt.Sprintf("%d", order.Id),
			LinkTable: fmt.Sprintf("m_trade_order"),
			Ago:       material.Num,
			Num:       total,
			After:     material.Num + total,
			Remarks:   "市场-出售商品获得",
			AddTime:   time.Now().Format(time.DateTime),
		}
		_, err = collection.InsertOne(ctx, materialLog)
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketCreateOrder err:mongo创建材料日志失败 req=%v,dbErr=%v", order.UID, order, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
		//6.修改商品信息
		trade.SalesNum += order.Num
		up = make(map[string]any)
		up["sales_num"] = gorm.Expr("sales_num+?", order.Num)
		if trade.SyNum == 0 && trade.SalesNum == trade.Num {
			up["status"] = 2
		}
		err = tx.Model(trade).Where("id=? AND status=0", order.TradeID).Updates(&up).Error
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketCreateOrder err:修改商品信息失败 req=%v,dbErr=%v", order.UID, order, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
	}
	//4.mongo创建订单
	collection := d.repo.Mongo.Db.Collection("trade_order")
	_, err = collection.InsertOne(ctx, order)
	if err != nil {
		logs.Error("[marketHandler]用户%d MarketCreateOrder err:mongo创建订单失败 req=%v,dbErr=%v", order.UID, order, err)
		tx.Rollback()
		return nil, biz.SqlError
	}
	tx.Commit()
	return order, nil
}

func (d *MarketDao) MarketOrderCancel(ctx context.Context, order *entity.MarketOrder) error {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	//1.查看商品列表
	trade := new(db.Trade)
	g := d.GetTrade(ctx, order.TradeID)
	if g == nil {
		return errors.New("无获取到商品数量")
	}
	//2.查看订单
	o := d.MongoGetMarketOrderByOrderNo(ctx, order.UID, order.OrderNo)
	if o.OrderNo == "" {
		return errors.New("未获取到订单")
	}
	//3.修改商品数量
	up := make(map[string]any)
	up["sy_num"] = gorm.Expr("sy_num+?", order.Num)
	//up["status"] = 0
	err := tx.Model(trade).Where("id=?", order.TradeID).Updates(up).Error
	if err != nil {
		return fmt.Errorf("修改数据库失败,err:%v", err)
	}
	//4.修改mongo商品订单状态
	collection := d.repo.Mongo.Db.Collection("trade_order")
	_, err = collection.UpdateOne(ctx, bson.D{
		{"uid", order.UID},
		{"orderNo", order.OrderNo},
		{"payStatus", entity.TradePayNone},
	}, bson.M{
		"$set": order,
	})
	if err != nil {
		tx.Rollback()
		return fmt.Errorf("修改订单状态失败,err=%v", err)
	}
	tx.Commit()

	return nil
}

func (d *MarketDao) MongoGetMarketOrderByOrderNo(ctx context.Context, uid uint, no string) *entity.MarketOrder {
	collection := d.repo.Mongo.Db.Collection("trade_order")
	singleResult := collection.FindOne(ctx, bson.D{
		{"uid", uid},
		{"orderNo", no},
		{"payStatus", entity.TradePayNone},
	})
	order := new(entity.MarketOrder)
	_ = singleResult.Decode(order)
	return order
}

func (d *MarketDao) MySellAll(ctx context.Context, page int, size int, uid uint) (int64, *[]db.TradeHasOneType) {
	data := new([]db.TradeHasOneType)
	var count int64
	DB := d.repo.DB.Client.WithContext(ctx).Model(db.Trade{}).Where("uid=? AND status=?", uid, 0)
	DB.Count(&count)
	DB.Order("created_at desc,status asc").Preload("Types").Preload("SellTypes").Scopes(db.Paginate(page, size)).Find(data)
	return count, data
}

func (d *MarketDao) MongoMarketOrder(ctx context.Context, id uint) *[]entity.MarketOrder {
	collection := d.repo.Mongo.Db.Collection("trade_order")
	cur, err := collection.Find(ctx, bson.D{
		{"tradeID", id},
	})
	if err != nil {
		return nil
	}
	var results []entity.MarketOrder
	for cur.Next(ctx) {
		var result entity.MarketOrder
		err = cur.Decode(&result)
		if err == mongo.ErrNoDocuments {
			return nil
		}
		results = append(results, result)
	}
	return &results
}

func (d *MarketDao) MarketSellWithdraw(ctx context.Context, uid uint, id uint, trade *db.TradeHasOneType, log *entity.TradeSellLog, materialLog *entity.MaterialLog) (*db.TradeHasOneType, *msError.Error) {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	_mdb := d.repo.Mongo
	mtx, _ := _mdb.Client.StartSession()
	_ = mtx.StartTransaction()
	defer mtx.EndSession(ctx)
	//1.查看是否有未支付的订单
	collection := d.repo.Mongo.Db.Collection("trade_order")
	count, err := collection.CountDocuments(ctx, bson.M{
		"tradeID":   id,
		"sellUID":   uid,
		"payStatus": entity.TradePayNone,
	})
	if err != nil {
		logs.Error("[marketHandler]用户%d MarketSellWithdraw err:查看是否有未支付的订单失败 req=%v,dbErr=%v", uid, trade, err)
		return nil, biz.SqlError
	}
	if count > 0 {
		logs.Error("[marketHandler]用户%d MarketSellWithdraw err:有未支付的订单无法操作 req=%v", uid, trade)
		return nil, biz.TradeNotError
	}
	//2.商品下架
	up := make(map[string]any)
	up["sy_num"] = trade.SyNum
	up["return_num"] = trade.ReturnNum
	up["status"] = trade.Status
	err = tx.Table(trade.TableName()).Where("id=? AND uid=?", id, uid).Updates(up).Error
	if err != nil {
		logs.Error("[marketHandler]用户%d MarketSellWithdraw err:商品下架失败 req=%v,dbErr=%v", uid, trade, err)
		return nil, biz.SqlError
	}
	//3.添加数量
	switch trade.Type {
	case 1:
		ship := new(db.WarehouseCard)
		err = tx.Model(ship).Where("id=? AND uid=?", trade.WID, uid).Update("is_freeze", false).Error
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketSellWithdraw err:修改舰船解冻失败 req=%v,dbErr=%v", uid, trade, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
	case 2:
		material := new(db.WarehouseMaterial)
		err = tx.Model(material).Where("id=? AND uid=?", trade.WID, uid).Update("num", gorm.Expr("num+?", trade.Num)).Error
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketSellWithdraw err:添加材料失败 req=%v,dbErr=%v", uid, trade, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
		//添加材料变动记录
		_, err = _mdb.Db.Collection("material_log").InsertOne(ctx, materialLog)
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketSellWithdraw err:添加材料变更失败 req=%v,dbErr=%v", uid, materialLog, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
	case 3:
		port := new(db.WarehouseEquip)
		err = tx.Model(port).Where("id=? AND uid=?", trade.WID, uid).Update("is_freeze", false).Error
		if err != nil {
			logs.Error("[marketHandler]用户%d MarketSellWithdraw err:修改港口解冻失败 req=%v,dbErr=%v", uid, trade, err)
			tx.Rollback()
			return nil, biz.SqlError
		}
	}

	//4.创建mongo下架订单记录
	_, err = _mdb.Db.Collection("trade_log").InsertOne(ctx, log)
	if err != nil {
		logs.Error("[marketHandler]用户%d MarketSellWithdraw err:创建mongo下架订单记录失败 req=%v,dbErr=%v", uid, materialLog, err)
		tx.Rollback()
		_ = mtx.AbortTransaction(ctx)
		return nil, biz.SqlError
	}
	_ = mtx.CommitTransaction(ctx)
	tx.Commit()
	return trade, nil
}

func (d *MarketDao) MarketOrderList(ctx context.Context, uid uint, req *request.PageMsg, status int) (int64, *[]entity.MarketOrder) {
	collection := d.repo.Mongo.Db.Collection("trade_order")
	whe := bson.D{
		{"uid", uid},
		{"payStatus", status},
	}
	count, err := collection.CountDocuments(ctx, whe)
	if err != nil {
		return 0, nil
	}
	var page, pageSize = int64(req.Page), int64(req.PageSize)
	option := options.Find()
	option.SetSort(bson.D{{"createTime", -1}}) //降序
	option.SetSkip((page - 1) * pageSize)
	option.SetLimit(pageSize)

	cur, err := collection.Find(ctx, whe, option)
	if err != nil {
		return 0, nil
	}
	var results []entity.MarketOrder
	for cur.Next(ctx) {
		var result entity.MarketOrder
		err = cur.Decode(&result)
		if err == mongo.ErrNoDocuments {
			return 0, nil
		}
		results = append(results, result)
	}
	return count, &results
}

func (d *MarketDao) MongoGetOrderByOrderNo(ctx context.Context, uid uint, orderNo string) *entity.MarketOrder {
	collection := d.repo.Mongo.Db.Collection("trade_order")
	singleResult := collection.FindOne(ctx, bson.D{
		{"uid", uid},
		{"orderNo", orderNo},
		{"payStatus", entity.TradePayNone},
	})
	order := new(entity.MarketOrder)
	_ = singleResult.Decode(order)
	return order
}

func (d *MarketDao) OrderPay(ctx context.Context, order *entity.MarketOrder, response string) error {
	_db := d.repo.DB.Client.WithContext(ctx)
	tx := _db.Begin()
	_mdb := d.repo.Mongo
	mtx, _ := _mdb.Client.StartSession()
	_ = mtx.StartTransaction()
	defer mtx.EndSession(ctx)
	//1.把订单状态改为已完成
	_, err := _mdb.Db.Collection("trade_order").UpdateOne(ctx, bson.D{
		{"_id", order.Id},
		{"payStatus", entity.TradePayNone},
	}, bson.M{
		"$set": bson.M{
			"payStatus": entity.TradePay,
			"payTime":   time.Now().Unix(),
			"payNotify": response,
		},
	})
	if err != nil {
		return fmt.Errorf("修改订单数据失败,err=%v", err)
	}
	//2.查看市场商品信息
	trade := new(db.Trade)
	_db.Model(trade).Where("id=? AND status=0", order.TradeID).First(trade)
	if trade == nil || trade.ID == 0 {
		_ = mtx.AbortTransaction(ctx)
		return fmt.Errorf("查询商品数据失败")
	}
	//3.添加市场购买的商品
	switch trade.Type {
	case 1: //卡牌
		warehouse := new(db.WarehouseCard)
		err = tx.Model(warehouse).Where("id=?", trade.WID).Updates(map[string]any{
			"uid":       order.UID,
			"is_freeze": false,
		}).Error
		if err != nil {
			_ = mtx.AbortTransaction(ctx)
			return fmt.Errorf("修改卡牌数据错误,err=%v", err)
		}
	case 2: //材料
		material := new(db.WarehouseMaterial)
		_db.Model(material).Where("uid=? AND type_id=?", order.UID, order.TypeID).First(material)
		if material == nil || material.ID == 0 { //不存在 添加
			material = &db.WarehouseMaterial{
				UID:    order.UID,
				TypeID: order.TypeID,
				Num:    order.Num,
			}
			err = tx.Model(material).Create(material).Error
		} else { //存在修改
			err = tx.Model(material).Where("id=?", material.ID).Update("num", gorm.Expr("num+?", order.Num)).Error
		}
		if err != nil {
			_ = mtx.AbortTransaction(ctx)
			return fmt.Errorf("添加或修改材料数据错误,err=%v", err)
		}
		//添加仓库材料记录
		collection := d.repo.Mongo.Db.Collection("material_log")
		materialLog := &entity.MaterialLog{
			UID:       order.UID,
			WID:       order.TradeID,
			TypeID:    material.TypeID,
			TypeName:  order.TypeName,
			TypeImg:   order.TypeImg,
			LinkID:    fmt.Sprintf("%d", order.Id),
			LinkTable: fmt.Sprintf("m_trade_order"),
			Ago:       material.Num,
			Num:       order.Num,
			After:     material.Num + order.Num,
			Remarks:   "市场-购买商品",
			AddTime:   time.Now().Format(time.DateTime),
		}
		_, err = collection.InsertOne(ctx, materialLog)
		if err != nil {
			tx.Rollback()
			_ = mtx.AbortTransaction(ctx)
			return fmt.Errorf("添加材料记录数据错误,err=%v", err)
		}
	case 3: //装备
		warehouse := new(db.WarehouseEquip)
		err = tx.Model(warehouse).Where("id=?", trade.WID).Updates(map[string]any{
			"uid":       order.UID,
			"is_freeze": false,
		}).Error
		if err != nil {
			_ = mtx.AbortTransaction(ctx)
			return fmt.Errorf("修改装备数据错误,err=%v", err)
		}
	default:
		_ = mtx.AbortTransaction(ctx)
		return fmt.Errorf("商城商品无(卡牌|港口|装备)以外的其它类型")
	}
	//3.添加市场的出售值
	trade.SalesNum += order.Num
	up := make(map[string]any)
	up["sales_num"] = gorm.Expr("sales_num+?", order.Num)
	if trade.SyNum == 0 && trade.SalesNum == trade.Num {
		up["status"] = 2
	}
	err = tx.Model(trade).Where("id=? AND status=0", order.TradeID).Updates(&up).Error
	if err != nil {
		tx.Rollback()
		_ = mtx.AbortTransaction(ctx)
		return fmt.Errorf("修改市场出售数据错误,err=%v", err)
	}
	_ = mtx.CommitTransaction(ctx)
	tx.Commit()
	if response != "" {
		r := new(hall.ReturnResAsynchronous)
		_ = json.Unmarshal([]byte(response), r)
		go d.baseDao.TimingMarket(r, order)
	}

	return nil
}

func (d *MarketDao) MarketBuyList(ctx context.Context) *[]entity.MarketOrder {
	collection := d.repo.Mongo.Db.Collection("trade_order")
	whe := bson.D{
		{"payStatus", entity.TradePayNone},
	}
	cur, err := collection.Find(ctx, whe)
	if err != nil {
		return nil
	}
	var results []entity.MarketOrder
	for cur.Next(ctx) {
		var result entity.MarketOrder
		err = cur.Decode(&result)
		if err == mongo.ErrNoDocuments {
			return nil
		}
		results = append(results, result)
	}
	return &results
}

func NewMarketDao(m *repo.Manager) *MarketDao {
	return &MarketDao{
		repo:    m,
		baseDao: NewBaseDao(m),
	}
}
